home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / irix / tools / getopt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  4.8 KB  |  211 lines

  1. /*------------------------------------------------------------------------
  2.  * $Header: /d1/dist/tools/RCS/getopt.c,v 1.1 1991/07/19 14:18:35 carlson Exp $
  3.  *
  4.  * getopt.c    My getopt function.
  5.  *
  6.  * Synopsis:
  7.  *    getopt [-o <name>] <optstring> <options>
  8.  *
  9.  * Description:
  10.  *    Identical to the system 'getopt' command except that it has the
  11.  *    additional functions:
  12.  *    1.    If the -o option is provided, checks a file called
  13.  *        .getopt for a line that begins with <name>.  It then
  14.  *        uses the options provided on this line as defaults.
  15.  *    2.    Normally, the option string contains letters and,
  16.  *        optionally, colons to indicate that an option must
  17.  *        be followed by an argument.  In addition, we allow
  18.  *        a '=' to indicate that an option might be followed
  19.  *        immediately by an argument (with no white space),
  20.  *        a '+' to indicate that an option might be followed
  21.  *        by an argument (with white space).
  22.  *
  23.  * Revision history:
  24.  *    $Log: getopt.c,v $
  25.  * Revision 1.1  1991/07/19  14:18:35  carlson
  26.  * Initial revision
  27.  *
  28.  *-----------------------------------------------------------------------*/
  29.  
  30. #include <stdio.h>
  31. #include <errno.h>
  32. #include <ctype.h>
  33. #include <string.h>
  34.  
  35. char opt_name[50], opt_string[50], flg_string[50];
  36. char buffer[256], *t_argv[50];
  37.  
  38. char act_opts[50], act_flgs[50], *act_args[50], *rem_args[50];
  39.  
  40. main (argc, argv)
  41.   int argc;
  42.   char *argv[];
  43. {
  44.     register int i, cur_opt;
  45.     register char *cp;
  46.  
  47.     if (argc < 3) {
  48.     fprintf (stderr, "Usage: %s [-o <name>] <optstring> <options>\n",
  49.          argv[0]);
  50.     fprintf (stderr,
  51.          "       <name> = Name found in file .getopt to provide\n");
  52.     fprintf (stderr,
  53.          "                default options.\n");
  54.     fprintf (stderr,
  55.          "       <optstring> = Option characters to allow.  The\n");
  56.     fprintf (stderr,
  57.          "                following additional characters mean:\n");
  58.     fprintf (stderr,
  59.          "                : - Required argument follows.\n");
  60.     fprintf (stderr,
  61.          "                = - Optional argument follows with no\n");
  62.     fprintf (stderr,
  63.          "                    white space.\n");
  64.     fprintf (stderr,
  65.          "                + - Optional argument follows.\n");
  66.     exit (0);
  67.     }
  68.  
  69. /*----
  70.  * If the option -o is provided, search through the file .getopt (if it
  71.  * exists) for a line that is equal to argv[2].
  72.  *
  73.  * If there is a line that matches argv[2], build an array similar to
  74.  * argv with the options found.
  75.  *----*/
  76.  
  77.     cur_opt = 1;
  78.     if (strcmp (argv[1], "-o") == 0) {
  79.     FILE *fp;
  80.  
  81.     if ((fp = fopen (".getopt", "r")) != NULL) {
  82.         while (fgets (buffer, sizeof (buffer), fp)) {
  83.         cp = strtok (buffer, " \t");
  84.         if (strcmp (cp, argv[2]) == 0)
  85.             break;
  86.         }
  87.  
  88.         if (cp) {
  89.         for (i = 0; (cp = strtok (NULL, " \t")); i++) 
  90.             t_argv[i] = cp;
  91.         t_argv[i] = NULL;
  92.  
  93.         do_opts (t_argv, 0, i);
  94.         }
  95.  
  96.         fclose (fp);
  97.     }
  98.  
  99.     cur_opt = 3;
  100.     }
  101.  
  102.     for (cp = argv[cur_opt++], i = 0; *cp; cp++, i++) {
  103.     opt_string[i] = *cp;
  104.     flg_string[i] = (*(cp+1) && strchr (":+=", *(cp+1))) ? *(++cp) : '\0';
  105.     }
  106.     opt_string[i] = '\0';
  107.  
  108.     do_opts (argv, cur_opt, argc);
  109.  
  110.     for (i = 0; act_opts[i]; i++) {
  111.     putchar ('-');
  112.     putchar (act_opts[i]);
  113.     putchar (' ');
  114.     if (act_args[i]) {
  115.         fputs (act_args[i], stdout);
  116.         putchar (' ');
  117.     }
  118.     }
  119.  
  120.     putchar ('-');
  121.     putchar ('-');
  122.  
  123.     for (i = 0; rem_args[i]; i++) {
  124.     putchar (' ');
  125.     fputs (rem_args[i], stdout);
  126.     }
  127.  
  128.     putchar ('\n');
  129. }
  130.  
  131. do_opts (argv, first, last)
  132.   char *argv[];
  133.   int first, last;
  134. {
  135.     register int i, j, k, l;
  136.     register char *cp;
  137.  
  138. /*----
  139.  * Loop through arguments and check each if it is an expected
  140.  * option.
  141.  *
  142.  * i = index into argv.
  143.  * j = misc.
  144.  * k = index into act_opts.
  145.  * l = index into character position of current argv[i].
  146.  *----*/
  147.  
  148.     for (i = first, k = 0; i < last; i++) {
  149.     if (argv[i][0] == '-') {
  150.         if (argv[i][1] == '-') {
  151.         i++;
  152.         break;
  153.         }
  154.         for (l = 1; argv[i][l]; ) {
  155.         if ((cp = strchr (opt_string, argv[i][l]))) {
  156.             act_opts[k] = argv[i][l];
  157.             act_args[k] = NULL;
  158.             j = cp - opt_string;
  159.             switch (flg_string[j]) {
  160.               case ':':        /* Must be an argument */
  161.             if (argv[i][++l]) {
  162.                 act_args[k] = &argv[i][l];
  163.             } else {
  164.                 if (++i >= last) {
  165.                 act_args[k] = "NOARG";
  166.                 } else {
  167.                 act_args[k] = argv[i];
  168.                 }
  169.             }
  170.             l = strlen (argv[i]);
  171.             k++;
  172.             break;
  173.  
  174.               case '=':        /* There may be an immediate arg */
  175.             if (argv[i][++l]) {
  176.                 act_args[k] = &argv[i][l];
  177.                 l = strlen (argv[i]);
  178.             }
  179.             k++;
  180.             break;
  181.  
  182.               case '+':        /* Thare may be an arg */
  183.             if (!argv[i][++l] && (argv[i+1][0] != '-')) {
  184.                 act_args[k] = argv[++i];
  185.                 l = strlen (argv[i]);
  186.             }
  187.             k++;
  188.             break;
  189.  
  190.               default:
  191.             l++;
  192.             k++;
  193.             }
  194.         } else {        /* Not recognized option */
  195.             fprintf (stderr, "Unrecognized option: %c\n",
  196.                  argv[i][l++]);
  197.         }
  198.         }
  199.     } else {
  200.         break;
  201.     }
  202.     }
  203.  
  204.     act_opts[k] = '\0';
  205.  
  206.     for (k = 0; i < last; i++, k++) {
  207.     rem_args[k] = argv[i];
  208.     }
  209.     rem_args[k] = NULL;
  210. }
  211.